package org.example.jdbc_study.tcp;

import lombok.extern.slf4j.Slf4j;
import org.example.jdbc_study.domain.vo.MyUserVo;
import org.example.jdbc_study.common.util.MessageUtil;
import org.example.jdbc_study.web.MyUserController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务socket
 *
 * @author 欧阳劲驰
 * @since 0.0.1
 */
@Slf4j
@Component
public class SocketServer implements ApplicationRunner {
    @Autowired
    MyUserController myUserController;

    /**
     * <p>运行</p>
     * {@inheritDoc}
     *
     * @param args 启动上下文
     * @throws Exception 异常
     */
    @Override
    public void run(ApplicationArguments args) throws IOException {
        //从端口创建ServerSocket
        try (ServerSocket serverSocket = new ServerSocket(10040)) {
            log.info("ServerSocket启动成功,端口为10040");
            //客户端数量
            int count = 0;
            //ServerSocket未关闭则一直循环
            while (!serverSocket.isClosed()) {
                //侦听并接收的客户端Socket
                Socket socket = serverSocket.accept();
                log.info("客户端已连接,信息为" + socket);
                //使用新线程运行Socket
                new Thread(() -> {
                    try {
                        //如socket未关闭,则始终循环,read方法会阻塞线程故死循不会消耗性能
                        while (!socket.isClosed()) {
                            //字节数组缓存
                            byte[] b = new byte[1024];
                            log.info("Socket等待读取数据");
                            //read等待,并将输入流读入缓存
                            int r = socket.getInputStream().read(b);
                            //判断read长度,如小于0表示发生异常或被断开
                            if (r > -1) {
                                //接收转换后的字符串
                                String data = new String(b);
                                log.info("获取到字符串:" + data);
                                //解码字符串
                                MyUserVo myUserVo = MessageUtil.decoding(data);
                                //数据存入数据库
                                boolean added = (myUserVo != null) && myUserController.addMyUser(myUserVo);
                                // 响应客户端请求
                                OutputStream outputStream = socket.getOutputStream();
                                outputStream.write(Boolean.toString(added).getBytes());
                                // 清空输出流缓冲区数据
                                outputStream.flush();
                                log.info("发送数据:" + added);
                            } else {
                                //异常处理:关闭socket
                                socket.close();
                                log.error("input流发送异常,socket被远程关闭,线程结束");
                            }
                        }
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).start();
                //记录客户端数量
                count++;
                log.info(("客户端数量" + count));
            }
        }
    }
}
